package com.jm.programming.stream;

import com.jm.programming.stream.pojo.Author;
import com.jm.programming.stream.pojo.Book;
import com.jm.programming.stream.utils.CreateDataUtil;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description
 * @date 2022/7/7 8:46
 */
public class StreamOverMain {
    public static void main(String[] args) {
        reduceMinAge();
    }

    /**
     * 使用reduce求出所有最小作者年龄
     * @return age
     */
    static int reduceMinAge(){
        List<Author> authors = CreateDataUtil.getAuthors();
        Integer reduce =
                authors.stream()
                        .distinct()
                        .map(author -> author.getAge())
                        .reduce(Integer.MAX_VALUE, (result, element) -> result > element ? element : result);
        System.out.println(reduce);
        return reduce;
    }

    /**
     * 使用reduce求出所有最大作者年龄
     * @return age
     */
    static int reduceMaxAge(){
        List<Author> authors = CreateDataUtil.getAuthors();
        Integer reduce =
                authors.stream()
                        .distinct()
                        .map(author -> author.getAge())
                        .reduce(Integer.MIN_VALUE, (result, element) -> result < element ? element : result);
        System.out.println(reduce);
        return reduce;
    }

    /**
     * 使用reduce求出所有作者年龄的和
     * @return age
     */
    static int reduceAdd(){
        List<Author> authors = CreateDataUtil.getAuthors();
        Integer reduce =
                authors.stream()
                        .distinct()
                        .map(author -> author.getAge())
                        .reduce(0, (result, element) -> result + element);
        System.out.println(reduce);
        return reduce;
    }

    /**
     * 获取年龄最小的元素
     */
    static void findFirst(){
        List<Author> authors = CreateDataUtil.getAuthors();
        Optional<Author> any = authors.stream()
                .sorted((o1, o2) -> o1.getAge() - o2.getAge())
                .findFirst();
        System.out.println(any.get());
    }

    /**
     * 获取年龄大于十八的任意一个元素
     */
    static void findAny(){
        List<Author> authors = CreateDataUtil.getAuthors();
        Optional<Author> any = authors.stream()
                                        .filter(author -> author.getAge() > 18)
                                        .findAny();
        System.out.println(any.get());
    }

    /**
     * 判断是否所有作家都 没有 超过一百岁
     * @return boolean
     */
    static boolean noneMatch(){
        List<Author> authors = CreateDataUtil.getAuthors();
        boolean b =
                authors.stream()
                        .noneMatch(author -> author.getAge() > 100);
        System.out.println(b);
        return b;
    }

    /**
     * 判断是否所有作家都是成年人
     * @return boolean
     */
    static boolean allMatch(){
        List<Author> authors = CreateDataUtil.getAuthors();
        boolean b =
                authors.stream()
                        .allMatch(author -> author.getAge() >= 18);
        System.out.println(b);
        return b;
    }

    /**
     * 判断是否存在29岁以上的作家
     * @return boolean
     */
    static boolean anyMatch(){
        List<Author> authors = CreateDataUtil.getAuthors();
        boolean b =
                authors.stream()
                        .anyMatch(author -> author.getAge() > 29);
        System.out.println(b);
        return b;
    }

    /**
     * 返回一个map：
     *              k - 作者名
     *              v - 图书集合
     * @return collect
     */
    static Map<String, List<Book>> infoByCollect(){
        List<Author> authors = CreateDataUtil.getAuthors();
        Map<String, List<Book>> collect =
                                        authors.stream()
                                                .distinct()
                                                .collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));
        return collect;
    }

    /**
     * 返回一个存放所有书名的集合
     * @return collect
     */
    static Set<Book> booksByCollect(){
        List<Author> authors = CreateDataUtil.getAuthors();
        Set<Book> collect =
                authors.stream()
                        .flatMap(author -> author.getBooks().stream())
                        .collect(Collectors.toSet());
        System.out.println(collect);
        return collect;
    }

    /**
     * 返回一个存放所有作者名字的集合
     * @return collect
     */
    static List<String> namesByCollect(){
        List<Author> authors = CreateDataUtil.getAuthors();
        List<String> collect =
                authors.stream()
                        .map(author -> author.getName())
                        .collect(Collectors.toList());
        System.out.println(collect);
        return collect;
    }

    /**
     * 获取数据的最低分
     */
    static void min(){
        List<Author> authors = CreateDataUtil.getAuthors();
        Optional<Integer> count = authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .map(book -> book.getScore())
                .min((b1,b2) -> b1 - b2);
        System.out.println(count.get());
    }

    /**
     * 获取数据的最高分
     */
    static void max(){
        List<Author> authors = CreateDataUtil.getAuthors();
        Optional<Integer> count = authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .map(book -> book.getScore())
                .max((b1,b2) -> b1 - b2);
        System.out.println(count.get());
    }

    /**
     * 获取图书的数目
     */
    static void count(){
        List<Author> authors = CreateDataUtil.getAuthors();
        long count = authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .distinct()
                .count();
        System.out.println(count);
    }

    /**
     * 打印流中元素，且去重
     */
    static void forEach(){
        List<Author> authors = CreateDataUtil.getAuthors();
        authors.stream()
                .distinct()
                .forEach(author -> System.out.println(author.getName()));
    }
}
